package ShapeManagement;

import java.awt.*;
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;
import java.io.FileNotFoundException;
import ShapeManagement.bounceboxframework.Shape;
import ShapeManagement.bouncebox.Circle;
import ShapeManagement.bouncebox.Square;
import ShapeManagement.bouncebox.Rectangle;
import ShapeManagement.bouncebox.Triangle;
import ShapeManagement.bouncebox.BounceBox;


public class ShapeService {
    /**
     * Parses a file containing shape definitions and creates corresponding Shape objects.
     * @param filePath Path to the file containing shape data
     * @return ArrayList of parsed Shape objects
     */
    public ArrayList<Shape> parseFile(String filePath) throws FileNotFoundException {
        ArrayList<Shape> shapes = new ArrayList<>();
        FileInputStream fileIn = new FileInputStream(filePath);
        Scanner scanner = new Scanner(fileIn);

        while (scanner.hasNext()) {
            String type = scanner.next();

            switch (type) {
                case "Circle":
                    int x = scanner.nextInt();
                    int y = scanner.nextInt();
                    int radius = scanner.nextInt();
                    Circle circle = new Circle(x, y, radius);

                    if (scanner.hasNextInt()) {
                        int vx = scanner.nextInt();
                        int vy = scanner.nextInt();
                        circle.setVelocity(vx, vy);

                        if (scanner.hasNextInt()) {
                            int r = scanner.nextInt();
                            int g = scanner.nextInt();
                            int b = scanner.nextInt();
                            circle.setColor(new Color(r, g, b));
                        }
                    } else if (scanner.hasNextInt()) {
                        int r = scanner.nextInt();
                        int g = scanner.nextInt();
                        int b = scanner.nextInt();
                        circle.setColor(new Color(r, g, b));
                    }

                    shapes.add(circle);
                    break;

                case "Square":
                    x = scanner.nextInt();
                    y = scanner.nextInt();
                    int width = scanner.nextInt();
                    Square square = new Square(x, y, width);

                    if (scanner.hasNextInt()) {
                        int vx = scanner.nextInt();
                        int vy = scanner.nextInt();
                        square.setVelocity(vx, vy);

                        if (scanner.hasNextInt()) {
                            int r = scanner.nextInt();
                            int g = scanner.nextInt();
                            int b = scanner.nextInt();
                            square.setColor(new Color(r, g, b));
                        }
                    } else if (scanner.hasNextInt()) {
                        int r = scanner.nextInt();
                        int g = scanner.nextInt();
                        int b = scanner.nextInt();
                        square.setColor(new Color(r, g, b));
                    }

                    shapes.add(square);
                    break;

                case "Rectangle":
                    x = scanner.nextInt();
                    y = scanner.nextInt();
                    width = scanner.nextInt();
                    int height = scanner.nextInt();
                    Rectangle rectangle = new Rectangle(x, y, width, height);

                    if (scanner.hasNextInt()) {
                        int vx = scanner.nextInt();
                        int vy = scanner.nextInt();
                        rectangle.setVelocity(vx, vy);

                        if (scanner.hasNextInt()) {
                            int r = scanner.nextInt();
                            int g = scanner.nextInt();
                            int b = scanner.nextInt();
                            rectangle.setColor(new Color(r, g, b));
                        }
                    } else if (scanner.hasNextInt()) {
                        int r = scanner.nextInt();
                        int g = scanner.nextInt();
                        int b = scanner.nextInt();
                        rectangle.setColor(new Color(r, g, b));
                    }

                    shapes.add(rectangle);
                    break;

                case "Triangle":
                    x = scanner.nextInt();
                    y = scanner.nextInt();
                    int base = scanner.nextInt();
                    height = scanner.nextInt();
                    Triangle triangle = new Triangle(x, y, base, height);

                    if (scanner.hasNextInt()) {
                        int vx = scanner.nextInt();
                        int vy = scanner.nextInt();
                        triangle.setVelocity(vx, vy);

                        if (scanner.hasNextInt()) {
                            int r = scanner.nextInt();
                            int g = scanner.nextInt();
                            int b = scanner.nextInt();
                            triangle.setColor(new Color(r, g, b));
                        }
                    } else if (scanner.hasNextInt()) {
                        int r = scanner.nextInt();
                        int g = scanner.nextInt();
                        int b = scanner.nextInt();
                        triangle.setColor(new Color(r, g, b));
                    }

                    shapes.add(triangle);
                    break;

                default:
                    System.out.println(type + " is not a recognized shape");
                    scanner.nextLine();
            }
        }

        scanner.close();
        return shapes;
    }

    /**
     * Counts the number of shapes by their type.
     * @param shapes List of shapes to count
     * @return HashMap mapping shape class names to their counts
     */
    public HashMap<String, Integer> countByType(ArrayList<Shape> shapes) {
        HashMap<String, Integer> countMap = new HashMap<>();

        for (Shape shape : shapes) {
            String className = shape.getClass().getSimpleName();
            countMap.put(className, countMap.getOrDefault(className, 0) + 1);
        }
        return countMap;
    }

    /**
     * Calculates the total area of all shapes.
     * @param shapes List of shapes to calculate area for
     * @return Total area of all shapes
     */
    public double totalArea(ArrayList<Shape> shapes){
        double total = 0;

        for (Shape shape : shapes) {
            total += shape.getMass();
        }
        return total;
    }

    /**
     * Displays shapes in a visual bounce box window.
     * @param shapes List of shapes to display
     */
    public void displayShapes(ArrayList<Shape> shapes){
        BounceBox box = new BounceBox(700, 500);

        for (Shape shape : shapes) {
            box.addShape(shape);
        }
        box.start();
    }
}